package com.nvwa.coding.el;

import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.ParserContext;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;

/**
 * EL表达式解析工具
 */
@Slf4j
public final class ExpressionLanguageHelper {
    private static final ParserContext PARSER_CONTEXT;
    private static final SpelExpressionParser EXPRESSION_PARSER;

    static {
        PARSER_CONTEXT = new TemplateParserContext("${", "}");
        EXPRESSION_PARSER = new SpelExpressionParser();
    }

    /**
     * EL表达式解析，主要是解析占位符，将占位符替换为实际值
     *
     * @param expressionString EL表达式文本
     * @param rootObject       解析EL表达式占位符所需的根对象，将占位符替换为根对象对应属性的值
     * @return 返回解析后的EL表达式
     */
    public static String parseExpression(String expressionString, Object rootObject) {
        String result = EXPRESSION_PARSER.parseExpression(expressionString, PARSER_CONTEXT).getValue(rootObject, String.class);
        log.debug("EL解析：input:{}\toutput:{}", expressionString, result);
        return result;
    }

    /**
     * EL表达式解析，主要是对EL表达式进行运算
     *
     * @param expressionString  EL表达式
     * @param desiredResultType 需要返回的结果类型
     * @return 返回EL表达式执行结果
     */
    public static <T> T parseExpression(String expressionString, Class<T> desiredResultType) {
        T result = EXPRESSION_PARSER.parseExpression(expressionString).getValue(desiredResultType);
        log.debug("EL解析：input:{}\tdesiredResultType:{}\toutput:{}", expressionString, desiredResultType, result);
        return result;
    }

    /**
     * EL表达式解析，主要是对EL表达式进行运算
     *
     * @param expressionString  EL表达式
     * @param desiredResultType 需要返回的结果类型
     * @return 返回EL表达式执行结果
     */
    public static <T> T parseExpression(String expressionString, Object rootObject, Class<T> desiredResultType) {
        T result = parseExpression(parseExpression(expressionString, rootObject), desiredResultType);
        log.debug("EL解析：input:{}\tdesiredResultType:{}\toutput:{}", expressionString, desiredResultType, result);
        return result;
    }


    public static void main(String[] args) {
        Boolean result = parseExpression("2>=1.5", Boolean.TYPE);
        System.out.println("list = " + result);
    }
}
